<template>
  <div class="dynamic-form-generator">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="dynamicRules"
      :label-width="labelWidth"
      @submit.prevent
    >
      <!-- 根据schema.groups渲染分组标签页 -->
      <el-tabs v-if="schema.groups && schema.groups.length > 0" v-model="activeTab" type="border-card">
        <el-tab-pane
          v-for="group in sortedGroups"
          :key="group.key"
          :label="group.label"
          :name="group.key"
        >
          <div class="group-content">
            <p v-if="group.description" class="group-description">
              {{ group.description }}
            </p>
            <DynamicField
              v-for="field in getFieldsByGroup(group.key)"
              :key="field.key"
              :field="field"
              :value="formData[field.key]"
              :form-data="formData"
              @update:value="updateFieldValue"
              @validate="validateField"
            />
          </div>
        </el-tab-pane>
      </el-tabs>

      <!-- 无分组时直接渲染字段 -->
      <template v-else>
        <DynamicField
          v-for="field in sortedFields"
          :key="field.key"
          :field="field"
          :value="formData[field.key]"
          :form-data="formData"
          @update:value="updateFieldValue"
          @validate="validateField"
        />
      </template>

      <!-- 操作按钮 -->
      <div class="form-actions" v-if="showActions">
        <slot name="actions" :validate="validateForm" :reset="resetForm">
          <el-button @click="resetForm" v-if="mode !== 'view'">重置</el-button>
          <el-button type="primary" @click="handleSubmit" v-if="mode !== 'view'">
            {{ mode === 'create' ? '创建' : '保存' }}
          </el-button>
        </slot>
      </div>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import type { ConfigSchema, FieldSchema, FormGroup } from '@/types/schema'
import DynamicField from './DynamicField.vue'

interface Props {
  /** 配置Schema */
  schema: ConfigSchema
  /** 表单数据 */
  modelValue: Record<string, any>
  /** 表单模式 */
  mode?: 'create' | 'edit' | 'view'
  /** 标签宽度 */
  labelWidth?: string
  /** 是否显示操作按钮 */
  showActions?: boolean
}

interface Emits {
  (e: 'update:modelValue', value: Record<string, any>): void
  (e: 'submit', value: Record<string, any>): void
  (e: 'validate', result: { valid: boolean, errors: string[] }): void
  (e: 'field-change', field: string, value: any): void
}

const props = withDefaults(defineProps<Props>(), {
  mode: 'edit',
  labelWidth: '120px',
  showActions: true
})

const emit = defineEmits<Emits>()

// 响应式数据
const formRef = ref()
const activeTab = ref('')
const formData = ref<Record<string, any>>({})

// 计算属性
const sortedFields = computed(() => {
  return [...props.schema.fields].sort((a, b) => (a.order || 0) - (b.order || 0))
})

const sortedGroups = computed(() => {
  if (!props.schema.groups) return []
  return [...props.schema.groups].sort((a, b) => (a.order || 0) - (b.order || 0))
})

const dynamicRules = computed(() => {
  const rules: Record<string, any[]> = {}
  
  for (const field of props.schema.fields) {
    if (field.rules && field.rules.length > 0) {
      rules[field.key] = field.rules.map(rule => ({
        ...rule,
        trigger: getValidationTrigger(field.type)
      }))
    }
    
    // 添加必填验证
    if (field.required) {
      if (!rules[field.key]) rules[field.key] = []
      rules[field.key].unshift({
        required: true,
        message: `${field.label}不能为空`,
        trigger: getValidationTrigger(field.type)
      })
    }
  }
  
  return rules
})

// 方法
const getFieldsByGroup = (groupKey: string) => {
  return sortedFields.value.filter(field => field.group === groupKey)
}

const getValidationTrigger = (fieldType: string) => {
  switch (fieldType) {
    case 'select':
    case 'multiSelect':
    case 'boolean':
      return 'change'
    default:
      return 'blur'
  }
}

const updateFieldValue = (fieldKey: string, value: any) => {
  formData.value[fieldKey] = value
  emit('update:modelValue', formData.value)
  emit('field-change', fieldKey, value)
  
  // 检查字段依赖，可能需要更新其他字段的显示状态
  checkFieldDependencies(fieldKey, value)
}

const checkFieldDependencies = (changedField: string, value: any) => {
  // 检查其他字段是否依赖于当前变更的字段
  for (const field of props.schema.fields) {
    if (field.showWhen) {
      for (const condition of field.showWhen) {
        if (condition.field === changedField) {
          // 重新计算字段的显示状态
          // 这里可以添加更复杂的条件判断逻辑
        }
      }
    }
  }
}

const validateField = async (fieldKey: string) => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validateField(fieldKey)
    return true
  } catch (error) {
    return false
  }
}

const validateForm = async () => {
  if (!formRef.value) return { valid: false, errors: ['表单未初始化'] }
  
  try {
    await formRef.value.validate()
    
    // 执行Schema级别的验证
    const schemaValidation = validateWithSchema()
    
    emit('validate', schemaValidation)
    return schemaValidation
  } catch (error) {
    const validationResult = { valid: false, errors: ['表单验证失败'] }
    emit('validate', validationResult)
    return validationResult
  }
}

const validateWithSchema = () => {
  const errors: string[] = []
  
  // 执行全局验证规则
  if (props.schema.globalValidation) {
    for (const rule of props.schema.globalValidation) {
      // 这里可以执行自定义的全局验证逻辑
    }
  }
  
  // 执行字段间关联验证
  for (const field of props.schema.fields) {
    if (field.dependencies) {
      for (const dep of field.dependencies) {
        // 检查依赖字段的值
        const depValue = formData.value[dep]
        const currentValue = formData.value[field.key]
        
        // 这里可以添加依赖字段的验证逻辑
      }
    }
  }
  
  return { valid: errors.length === 0, errors }
}

const resetForm = () => {
  if (!formRef.value) return
  
  formRef.value.resetFields()
  
  // 重置为默认值
  initializeFormData()
}

const handleSubmit = async () => {
  const validation = await validateForm()
  if (validation.valid) {
    emit('submit', formData.value)
  }
}

const initializeFormData = () => {
  const newFormData: Record<string, any> = {}
  
  // 使用传入的数据
  if (props.modelValue) {
    Object.assign(newFormData, props.modelValue)
  }
  
  // 设置默认值
  for (const field of props.schema.fields) {
    if (field.defaultValue !== undefined && newFormData[field.key] === undefined) {
      newFormData[field.key] = field.defaultValue
    }
  }
  
  formData.value = newFormData
}

const isFieldVisible = (field: FieldSchema) => {
  if (field.visible === false) return false
  
  if (typeof field.visible === 'string') {
    // 这里可以实现表达式求值
    // 暂时简化处理
    return true
  }
  
  if (field.showWhen) {
    for (const condition of field.showWhen) {
      const fieldValue = formData.value[condition.field]
      
      switch (condition.operator) {
        case '==':
          if (fieldValue !== condition.value) return false
          break
        case '!=':
          if (fieldValue === condition.value) return false
          break
        case 'contains':
          if (Array.isArray(fieldValue) && !fieldValue.includes(condition.value)) return false
          break
        case 'in':
          if (!Array.isArray(condition.value) || !condition.value.includes(fieldValue)) return false
          break
      }
    }
  }
  
  return true
}

// 监听器
watch(() => props.modelValue, (newValue) => {
  if (newValue) {
    Object.assign(formData.value, newValue)
  }
}, { deep: true, immediate: true })

watch(() => props.schema, () => {
  initializeFormData()
  
  // 设置默认活动标签页
  if (props.schema.groups && props.schema.groups.length > 0) {
    activeTab.value = sortedGroups.value[0]?.key || ''
  }
}, { immediate: true })

// 生命周期
onMounted(() => {
  initializeFormData()
})
</script>

<style scoped>
.dynamic-form-generator {
  width: 100%;
}

.group-content {
  padding: 20px 0;
}

.group-description {
  margin: 0 0 20px 0;
  color: var(--config-editor-text-secondary);
  font-size: 14px;
  line-height: 1.5;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 30px;
  padding-top: 20px;
  border-top: 1px solid var(--config-editor-border);
}

:deep(.el-tabs__content) {
  padding: 0;
}

:deep(.el-form-item) {
  margin-bottom: 22px;
}
</style>
